<?php
class f_session_Database
{
    private $life_time;

    static $tableName = 'f_sessions';

    protected function __construct()
    {
        if (!$this->checkTable())
        {
            $this->initTable();
        }

        // Read the maxlifetime setting from PHP
        $this->life_time = get_cfg_var("session.gc_maxlifetime");

        // Register this object as the session handler
        session_set_save_handler(
                array(&$this, "open"),
                array(&$this, "close"),
                array(&$this, "read"),
                array(&$this, "write"),
                array(&$this, "destroy"),
                array(&$this, "gc")
        );
    }

    /**
     * @return f_session_Database
     */
    public static function getInstance()
    {
        return new self();
    }

    private function checkTable()
    {
        return f_database_Provider::getInstance()->hasTable(self::$tableName);
    }

    private function initTable()
    {
        $sql = 'CREATE TABLE `'.self::$tableName.'` (
           `session_id` varchar(100) NOT NULL default "",
           `session_data` text NOT NULL,
           `expires` int(11) NOT NULL default "0",
            PRIMARY KEY  (`session_id`)
            ) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_general_ci;';

        f_database_Provider::getInstance()->setQuery($sql)->execute();
    }

    public function open($save_path, $session_name)
    {
        global $sess_save_path;

        $sess_save_path = $save_path;

        return true;
    }

    public function close()
    {
        return true;
    }

    public function read($id)
    {
        $sql = 'SELECT `session_data` FROM `'.self::$tableName.'` WHERE `session_id` = :id AND `expires` > :time';

        return f_database_Provider::getInstance()->setQuery($sql)->execute(array('id' => $id, 'time' => time()))->getQueryResult(PDO::FETCH_COLUMN);
    }

    public function write($id, $data)
    {
        $sql = 'REPLACE `'.self::$tableName.'` (`session_id`,`session_data`,`expires`) VALUES(:id,:data,:time)';

        f_database_Provider::getInstance()->setQuery($sql)->execute(array('id' => $id, 'data' => $data, 'time' => time() + $this->life_time));

        return true;
    }

    public function destroy($id)
    {
        $sql = 'DELETE FROM `'.self::$tableName.'` WHERE `session_id`=:id';

        f_database_Provider::getInstance()->setQuery($sql)->execute(array('id' => $id));

        return true;
    }

    public function gc()
    {
        f_database_Provider::getInstance()->executeQuery('DELETE FROM `'.self::$tableName.'` WHERE `expires` < UNIX_TIMESTAMP();');

        return true;
    }

}